import axios from "axios";
import { getToken } from "@/utils/cache";
// 时间同步模块骨架：仅接口与最小实现，不包含具体请求逻辑

let offsetMs = 0; // serverNow - clientNow
let lastSyncAt: number | null = null;

export function getCalibratedTimestamp(): number {
  return Date.now() + offsetMs;
}

export function updateOffsetFromServer(serverNowMs: number): void {
  offsetMs = serverNowMs - Date.now();
  lastSyncAt = Date.now();
}

export async function initTimeSync(): Promise<void> {
  // 预留：在此调用后端时间接口
  // 仅骨架，不直接 import 以免产生循环依赖；在 main.ts 调用方去执行
}

export function getTimeSyncState() {
  return { offsetMs, lastSyncAt };
}

/**
 * 直接向后端获取服务器毫秒时间戳，用于签名。
 * 注意：使用“裸”axios 实例，避免触发全局拦截器从而形成递归。
 */
export async function getServerTimestamp(baseURL?: string): Promise<string> {
  try {
    const instance = axios.create({ baseURL: baseURL || "/" });
    const token = getToken();
    const headers: Record<string, string | boolean> = { __skipSign: true as any };
    if (token) {
      headers["token"] = token;
      headers["Authorization"] = `Bearer ${token}`;
    }
    // 端点候选：优先使用 App 端，再回退到 Web 端（或反之）
    const candidates: string[] = [];
    const preferApp = !!(baseURL && baseURL.includes("/v2"));
    // App 端优先 platform/time，其次 timestamps/current；Web 端相反
    if (preferApp) {
      candidates.push("platform/time", "timestamps/current");
    } else {
      candidates.push("timestamps/current", "platform/time");
    }

    let d: any;
    let lastError: unknown;
    for (const url of candidates) {
      try {
        const res = await instance.get(url, { headers });
        d = (res?.data?.data ?? res?.data) as any;
        // 命中即退出循环
        break;
      } catch (e) {
        lastError = e;
        d = undefined;
      }
    }
    if (typeof d === "undefined") {
      throw lastError || new Error("SERVER_TIME_UNAVAILABLE");
    }
    
    let raw: any = d;
    if (typeof d === "object" && d) {
      if (Object.prototype.hasOwnProperty.call(d, "now")) raw = d.now;
      else if (Object.prototype.hasOwnProperty.call(d, "timestamps")) raw = d.timestamps;
      else if (Object.prototype.hasOwnProperty.call(d, "time")) raw = d.time;
    }
    const ts = String(raw ?? "").trim();
    if (!ts) {
      throw new Error("SERVER_TIME_INVALID");
    }
    // 直接返回后端提供的原始时间戳字符串（可能是秒，也可能是毫秒）
    return ts;
  } catch {
    // 严格模式：只允许使用后端时间戳，获取失败则抛错
    throw new Error("SERVER_TIME_UNAVAILABLE");
  }
}

/**
 * 专用：获取 Web 端时间戳（优先 timestamps/current，再回退 platform/time）
 */
export async function getWebServerTimestamp(baseURL?: string): Promise<string> {
  // 仅请求 /timestamps/current（Web 端）
  const webBase = baseURL || "/";
  const instance = axios.create({ baseURL: webBase });
  const token = getToken();
  const headers: Record<string, string | boolean> = { __skipSign: true as any };
  if (token) {
    headers["token"] = token;
    headers["Authorization"] = `Bearer ${token}`;
  }
  const res = await instance.get("timestamps/current", { headers });
  const d: any = (res?.data?.data ?? res?.data) as any;
  const raw = typeof d === "object" && d ? ("now" in d ? d.now : ("timestamps" in d ? d.timestamps : ("time" in d ? d.time : d))) : d;
  const ts = String(raw ?? "").trim();
  if (!ts) throw new Error("SERVER_TIME_INVALID");
  return ts;
}

/**
 * 专用：获取 App 端时间戳（优先 platform/time，再回退 timestamps/current）
 */
export async function getAppServerTimestamp(): Promise<string> {
  // 统一走 /v2 代理
  const appBase = "/v2";
  // 仅请求 /platform/time（App 端）
  const instance = axios.create({ baseURL: appBase });
  const token = getToken();
  const headers: Record<string, string | boolean> = { __skipSign: true as any };
  if (token) {
    headers["token"] = token;
    headers["Authorization"] = `Bearer ${token}`;
  }
  const res = await instance.get("platform/time", { headers });
  const d: any = (res?.data?.data ?? res?.data) as any;
  const raw = typeof d === "object" && d ? ("now" in d ? d.now : ("timestamps" in d ? d.timestamps : ("time" in d ? d.time : d))) : d;
  const ts = String(raw ?? "").trim();
  if (!ts) throw new Error("SERVER_TIME_INVALID");
  return ts;
}

/**
 * 并行获取两个端的时间戳（用于一次性生成 Web 与 App 的签名）
 * - 任何一端失败不会阻断另一端；返回可用值与错误信息
 */
export async function getDualServerTimestamps(options?: {
  webBaseURL?: string;
  appBaseURL?: string;
}): Promise<{ web?: string; app?: string; webError?: unknown; appError?: unknown }> {
  const webP = getWebServerTimestamp(options?.webBaseURL);
  const appP = getAppServerTimestamp();
  const [w, a] = await Promise.allSettled([webP, appP]);
  return {
    web: w.status === "fulfilled" ? w.value : undefined,
    app: a.status === "fulfilled" ? a.value : undefined,
    webError: w.status === "rejected" ? w.reason : undefined,
    appError: a.status === "rejected" ? a.reason : undefined
  };
}

